/**
 * @module NGS
 * @author Kevin MOU
 */
define(['js/eventObjective', 'js/oblist'], function(eventObj, Oblist) {
	var Objective = function(project, fields, obListFields, relations, extTBName, wo3, dbPool) {
		this.boundData = new BoundData("Objective"	+ $E.staff.epidSql + (extTBName||''));
		this.boundData.KeyInfoEdit("OBJECTIVE_GUID");
		this.boundData.setCreateInfo("CREATEDDATE", "CREATEDBY", $E.staff.id);
		this.boundData.setModifyInfo("MODIFIEDDATE", "MODIFIEDBY", $E.staff.id);
		this.flag = 0; // 0=读入的对象，1=新建的对象
		this.event = eventObj.create(project, extTBName);
		this.fields = fields;
		this.taskId = '';
		this.taskBoundData;
		this.extTBName = extTBName;
		this.project = project;
		this.wo3 = wo3;
		this.dbPool = dbPool || '';
		if (!wo3) {
			this.oblist = new Oblist(project, extTBName);
			this.obListFlag = 0; //0 --普通   1-完成(删除)    2-自定义状态    3-预约
			this.obListStatus = '';
			this.obListNextTime = '';
			this.obListExists = -1;
			this.obListGUID = '';
			this.obListHandleByID = '';
			this.obListHandleGroupID = '';
			this.obListValues = {};
			this.obListFields = obListFields;
			this.relations = relations;
			this.oldOBListStatus = '';
		}
	};

	Objective.prototype = {
		createData : function(otId, oId, mapId) {
			if (! otId)
				$F.err('Objective-createData', '无法根据objectiveGuid加载到数据');

			var a = this;
			a.flag = 1;
			a.setValue("OBJECTIVE_GUID", oId);
			a.setValue("OBJECTIVETYPE_ID", otId);
			if (mapId) {
				a.setValue("MAP_ID", mapId);
			}
			a.setValue("HANDLEBY_ID", $E.staff.id);
			a.setValue("HANDLEGROUP_ID", a.project.groupId);
			a.setValue("CUSTOMER_GUID", a.project.getCustomerGuid());
			a.setValue("OBJECTIVESTATUS", "OPEN");
			a.setupCurrentEvent();
		},
		
		/**
		 * 加载当前电话事务
		 */
		setupCurrentEvent : function(){
			var a = this;
			if (a.project.workDuration && a.project.cwInfo.callStartTime) {
                a.newEvent(a.project.cwInfo.eventGuid, a.project.cwInfo.callStartTime);
			}
		},

		loadObListValue : function() {
			var a = this;
			if (a.obListExists == -1) {
				if (a.flag == 0) {
					a.obListExists = 1;
					a.obListGUID = a.boundData.getValue("OBJECTIVE_GUID");
					a.oldOBListStatus = a.oblist.getValue("obstatus");
					
				}
			}
		},

		setObListValue : function(field, value) {
			if (this.obListFields[field.toLowerCase()]) {
				this.obListValues[field.toLowerCase()] = value;
			} else {
				$F.err('Objective - setObListValue', "OBList字段[" + field + "]不存在");
			}
		},
        getObListValue : function(field){
            if (this.obListFields[field.toLowerCase()]) {
                return this.obListValues[field.toLowerCase()];
            }
            return null;
        },
        
		modifyOneObjectiveValue : function(field, value) {
			this.setValue(field, value);
		},
        setValue : function(field, value) {
			var a = this;
			field = field.toLowerCase();
			if (a.fields[field]) {
				a.boundData.setValue(field, value, a.fields[field].type);
				if(!this.wo3) {
					if (a.relations[field]){
					    a.loadObListValue();
					    if (a.obListExists == 1){
					    	a.setObListValue(a.relations[field], value);
					     	$F.log('Objective - setValue', "ObList赋值["+ field +"]为:"+ value);
					    }else{
					     	// $F.err('Objective - setValue', "ObList记录不存在 ");
					    }
					}
				}
			} else
				$F.err('Objective - setValue', '字段[' + field + ']不存在');
		},

		getValue : function(field) {
			return this.boundData.getValue(field);
		},

		setOldValue : function(field, value, type) {
			this.boundData.OldValue(field, value, type);
		},

		getOldValue : function(field) {
			return this.boundData.getOldValue(field);
		},

		getId : function() {
			return this.boundData.getValue('OBJECTIVE_GUID')
		},

		getCustomerGuid : function() {
			return this.getValue('CUSTOMER_GUID')
		},

		newEvent : function(eventId, startTime) {
			var a = this;
			if (a.getValue('Event_GUID') == eventId) {
				return $F.log('Objective - newEvent', '发现相同的EVENT：' + eventId);
			}

			if (a.getValue("Last2Event_GUID") > "")
			    a.setValue("Last3Event_GUID", a.getValue("Last2Event_GUID"));
			if (a.getValue("Last1Event_GUID") > "")
			    a.setValue("Last2Event_GUID", a.getValue("Last1Event_GUID"));
			if (a.getValue("Event_GUID") > "")
			    a.setValue("Last1Event_GUID", a.getValue("Event_GUID"));

			a.setValue("Event_GUID", eventId);
			a.event.add(eventId, a.getId(), a.getValue("OBJECTIVETYPE_ID"), a.getValue("objectivestatus"), startTime);
			$F.log('Objective - newEvent', '新建Event[' + a.getId() + ']: ' + eventId);
		},
		
		getBoundData: function() {
            var a = this;
            if (a.event.hasEvents()) {
                var now = $PublicFun.now();
                var objectiveStatus = a.getValue("objectivestatus");
                if (this.project.cwInfo.callInfo && this.project.cwInfo.callInfo.dnis) {
                    a.setValue('obdnis', this.project.cwInfo.callInfo.dnis);
                }
                if (a.project.cwInfo.callStartTime) {
                    a.setValue("OBSTARTTIME", a.project.cwInfo.callStartTime);
                    var callEndTime;
                    if (a.project.cwInfo.callEndTime && new Date(a.project.cwInfo.callStartTime).getTime() < new Date(a.project.cwInfo.callEndTime).getTime()) {
                        callEndTime = a.project.cwInfo.callEndTime;
                    } else {
                        callEndTime = now;
                    }
                    a.setValue("OBENDTIME", callEndTime);

                    a.setValue("OBHandleBy", $E.staff.id);
                    a.setValue("OBHandleGroup", a.project.groupId);

                }

                // 判断是否有电话事务
                this.event.save(this.boundData, objectiveStatus);
            }
            
            //不论有无event，保存时候都会去考虑oblist
			if (!this.wo3) {
				this.loadObListValue();
				this.getOBListOBJ();
			}
			return this.boundData;
		},

		getXmlData : function() {
            return this.getBoundData().getData();
		},

		/**
		 * 工单三情况下处理appcall
		 * @param flag 0为删除，1为新建或更新
         * @param status APCALL,REPLY
         */
		handleAppCall : function(flag, status) {
			if (this.project.getParam("APCALL") == "1") {
				var objective = this.boundData;
				var elitetask = this.taskBoundData;
				if (flag == 0) {//delete
					var delAPCall = new BoundData("oblist_appcall" + $E.staff.epidSql + (this.extTBName||''));
					delAPCall.deleteFlag = 1;
					delAPCall.KeyInfoEdit("oblist_guid");
					delAPCall.NewValueEdit("oblist_guid", this.taskId);
					objective.SubTableAdd("SubDel", delAPCall);
				} else if (flag == 1) {//insert or update
					if(status){
						status = status.trim();
					} else {
						return;
					}
					var appCall = new BoundData("oblist_appcall" + $E.staff.epidSql + (this.extTBName||''));
					appCall.KeyInfoEdit("oblist_guid");
					appCall.NewValueEdit("oblist_guid", this.taskId);
					appCall.NewValueEdit("objective_guid", objective.getValue("objective_guid"));
					appCall.NewValueEdit("objectivetype_id", objective.getValue("objectivetype_id"));
					appCall.NewValueEdit("obstatus", status);
					appCall.NewValueEdit("expectstarttime", elitetask.getValue("expectstarttime"), $CONST.BoundType.F_Date);
					appCall.NewValueEdit("handleby_id", elitetask.getValue("handleby_id"));
					appCall.NewValueEdit("handlegroup_id", elitetask.getValue("handlegroup_id"));
					appCall.setModifyInfo("modifieddate", "modifiedby", $E.staff.id);
					objective.SubTableAdd("SubAPP", appCall);
				}
			}
		},


        setOBListStatus : function(vFlag, vStatus, vNextTime, vHandleBy, vHandleGroup){
            if (vFlag < 0 || vFlag > 3) {
                $F.log("Objective.setOBListStatus", "Arguments error: vFlag: " + vFlag);
                return -1;
            }
            this.obListFlag = vFlag;
            this.obListStatus = vStatus;
            this.obListNextTime = vNextTime;
            this.obListHandleByID = vHandleBy;
            this.obListHandleGroupID = vHandleGroup;
            this.loadObListValue();
        },


        getOBListOBJ : function() {
            var a = this;
            if (a.obListExists == 1 && a.obListFlag == 1) {// 对oblist删除
                this.boundData.SubTableAdd("OBLIST", this.getDeleteOBJ());
            } else if(a.obListExists == 1 && a.obListFlag == 0) {//更新
//                if(a.obListAttempt >= a.obListAttemptMax){//--- spring说不能删，会hold住，可能以后还要打开的
//                    this.boundData.SubTableAdd("OBLIST", this.getDeleteOBJ());//删除
//                }else{
                    this.boundData.SubTableAdd("OBLIST", this.getUpdateOBJ());
//                }
            } else if(a.obListFlag == 2 || a.obListFlag == 3) {
                this.boundData.SubTableAdd("OBLIST", this.getUpdateNewOBList());
            }
        },
        
        getDeleteOBJ : function() {
            $F.log("Objective", "Call getDeleteOBJ : " + this.obListGUID);
            var obList = new BoundData("oblist"	+ $E.staff.epidSql + (this.extTBName||''));
            obList.deleteFlag = 1;
            obList.KeyInfoEdit("oblist_guid");
            obList.NewValueEdit("oblist_guid", this.obListGUID);
            if (this.project.getParam("APCALL") == "1") {
                if(this.oldOBListStatus.trim() == "APCALL" || this.oldOBListStatus.trim() == "REPLY"){
                    var delAPCall = new BoundData("oblist_appcall"	+ $E.staff.epidSql + (this.extTBName||''));
                    delAPCall.deleteFlag = 1;
                    delAPCall.KeyInfoEdit("oblist_guid");
                    delAPCall.NewValueEdit("oblist_guid", this.obListGUID);
                    obList.SubTableAdd("SubDel", delAPCall);
                }
            }
            return obList;
        }
        ,getUpdateOBJ : function(){
            $F.log("Objective", "Call getUpdateOBJ : " + this.obListGUID);
            var now = $F.getDbTime();
            var obList = new BoundData("oblist"	+ $E.staff.epidSql + (this.extTBName||''));
            obList.setNotInsert(1);
            obList.KeyInfoEdit("oblist_guid");
            obList.NewValueEdit("oblist_guid", this.obListGUID);
            obList.setModifyInfo("modifieddate", "modifiedby", $E.staff.id);
            if ($F.isDate(this.obListNextTime)) {
                obList.NewValueEdit("expectstarttime", this.obListNextTime, $CONST.BoundType.F_Date);
            } else {
                obList.NewValueEdit("expectstarttime", this.getNextEndDate(now, "H", 1), $CONST.BoundType.F_Date);
            }
            if (!$F.isEmpty(this.obListHandleByID)) {
                obList.NewValueEdit("handleby_id", this.obListHandleByID);
            }
            if (!$F.isEmpty(this.obListHandleGroupID)) {
                obList.NewValueEdit("handlegroup_id", this.obListHandleGroupID);
            }
            if (this.project.getParam("APCALL") == "1") {
                if(this.oldOBListStatus.trim() == "APCALL" || this.oldOBListStatus.trim() == "REPLY"){
                    obList.NewValueEdit("obstatus", "OPEN");
                    var delAPCall = new BoundData("oblist_appcall"	+ $E.staff.epidSql + (this.extTBName||''));
                    delAPCall.deleteFlag = 1;
                    delAPCall.KeyInfoEdit("oblist_guid");
                    delAPCall.NewValueEdit("oblist_guid", this.obListGUID);
                    obList.SubTableAdd("SubDel", delAPCall);
                }
            }
            if (this.oldOBListStatus.trim() == "INPROC" || this.oldOBListStatus.trim() == "PDS_OB") {
                obList.NewValueEdit("obstatus", "OPEN");
            }
            this.saveOtherField(obList);
            return obList;
        }

        ,saveOtherField : function(obList) {
            if (!$.isEmptyObject(this.obListValues)) {
                for (var k in this.obListValues) {
                    obList.NewValueEdit(k, this.obListValues[k], this.obListFields[k.toLowerCase()].type);
                }
            }
        }

        ,getUpdateNewOBList : function() {
            $F.log("Objective", "Call getUpdateNewOBList : " + this.obListGUID);
            var now = $F.getDbTime();
            var obList = new BoundData("oblist"	+ $E.staff.epidSql + (this.extTBName||''));
            obList.KeyInfoEdit("objective_guid");
            obList.setCreateInfo("CREATEDDATE", "CREATEDBY", $E.staff.id);
            obList.setModifyInfo("modifieddate", "modifiedby", $E.staff.id);
            obList.NewValueEdit("objective_guid", this.boundData.getValue("objective_guid"));
            obList.NewValueEdit("oblist_guid", this.boundData.getValue("objective_guid"), $CONST.BoundType.F_String, 1);//最后一个参数1表示新建才赋值
            obList.NewValueEdit("objectivetype_id", this.boundData.getValue("objectivetype_id"), $CONST.BoundType.F_String, 1);
            obList.NewValueEdit("max_attempt", this.project.getParam("MAXATT"), $CONST.BoundType.F_Int, 1);

            if (!$F.isEmpty(this.obListHandleByID)) {
                obList.NewValueEdit("handleby_id", this.obListHandleByID);
            } else {
                obList.NewValueEdit("handleby_id", $E.staff.id, $CONST.BoundType.F_String, 1);
            }
            if (!$F.isEmpty(this.obListHandleGroupID)) {
                obList.NewValueEdit("handlegroup_id", this.obListHandleGroupID);
            } else {
                obList.NewValueEdit("handlegroup_id", this.project.groupId, $CONST.BoundType.F_String, 1);
            }

            if ($F.isDate(this.obListNextTime)) {
                obList.NewValueEdit("expectstarttime", this.obListNextTime, $CONST.BoundType.F_Date);
            } else {
                obList.NewValueEdit("expectstarttime", this.getNextEndDate(now, "H", 1), $CONST.BoundType.F_Date);
            }

            if (this.obListFlag == 2) {
                obList.NewValueEdit("obstatus", this.obListStatus);
            } else if(this.obListFlag == 3) {
                obList.NewValueEdit("obstatus", "APCALL");
            }
            if (this.project.getParam("APCALL") == "1") {
                if (this.obListStatus.trim() == "APCALL" || this.obListStatus.trim() == "REPLY") {
                    var obStatus = obList.getValue("obstatus");
                    if (obStatus == "APCALL" || obStatus == "REPLY") {
                        var appCall = new BoundData("oblist_appcall" + $E.staff.epidSql + (this.extTBName||''));
                        appCall.KeyInfoEdit("oblist_guid");
                        appCall.NewValueEdit("oblist_guid", this.obListGUID);
                        appCall.NewValueEdit("objective_guid", obList.getValue("objective_guid"));
                        appCall.NewValueEdit("objectivetype_id", obList.getValue("objectivetype_id"));
                        appCall.NewValueEdit("obstatus", obStatus);
                        appCall.NewValueEdit("expectstarttime", obList.getValue("expectstarttime"), $CONST.BoundType.F_Date);
                        appCall.NewValueEdit("handleby_id", obList.getValue("handleby_id"));
                        appCall.NewValueEdit("handlegroup_id", obList.getValue("handlegroup_id"));
                        appCall.setModifyInfo("modifieddate", "modifiedby", $E.staff.id);
                        obList.SubTableAdd("SubAPP", appCall);
                    }
                }
            }
            this.saveOtherField(obList);
            return obList;
        }
        ,getNextEndDate : function(date, c, v) {
            return $F.getNextEndDate(date, c, v, this.project.getCache($CONST.CacheName.FREE_DATE));
        }
	};

	return {
		/**
		 * 创建一个objective对象
		 * @method create
		 * @param project {object} 项目对象
		 * @param extTBName {string} 历史备份的数据的表后缀
		 * @return {Objective} Objective对象
		 */
		create: function(project, extTBName, wo3, dbPool) {
			// 读取objective和oblist的关系表
			var objectiveRelatoinWithObList = project.getCache('OBJECTIVE_OBLIST_RELATIONS');
			if (! objectiveRelatoinWithObList) {
				objectiveRelatoinWithObList = {};
				var str = project.getParam('OBJOBL');
				if (str) {
					var rs = str.split('--'), rsItem;
					for(var i=0; i<rs.length; i ++) {
						rsItem = rs[i].split('=');
						if (rsItem.length == 2) {
							objectiveRelatoinWithObList[rsItem[0].toLowerCase()] = rsItem[1].toLowerCase();
						}
					}
				}
				project.putCache('OBJECTIVE_OBLIST_RELATIONS', objectiveRelatoinWithObList);
			}
			//console.log(objectiveRelatoinWithObList);

			// 读取objective字典和oblist字典
			var objectiveFields = project.getCache('OBJECTIVE_FIELDS'),
				oblistFields = project.getCache('OBLIST_FIELDS');
			if (! objectiveFields) {
				objectiveFields = {};
				oblistFields = {};
				var sqls = ["Objective" + $E.staff.epidSql];
				if (!wo3) {
					sqls.push("Oblist" + $E.staff.epidSql);
				}
				// 加载objective字段列表
				$F.dataService('SystemDo3', {
					data : {
						token: project.token,
						dbPool: dbPool,
						sqls: sqls
					},
					async : false,
					digest: project.digest,
					success : function(data) {
						if (data.code > 0) {
							// console.log(data.value);
							// 获取objective字段名
							var columns = data.value[0].columns;
							for (var i=0; i<columns.length; i++) {
								objectiveFields[columns[i][0].toLowerCase()] = {
									length : columns[i][3],
									type : $PublicFun.fieldTypeStringToBoundType(columns[i][2])
								}
							}
							project.putCache('OBJECTIVE_FIELDS', objectiveFields);
							if (! wo3 && data.value[1].count > -1) {
								columns = data.value[1].columns;
								for (var i=0; i<columns.length; i++) {
									oblistFields[columns[i][0].toLowerCase()] = {
										length : columns[i][3],
										type : $PublicFun.fieldTypeStringToBoundType(columns[i][2])
									}
								}
								project.putCache('OBLIST_FIELDS', oblistFields);
							}
						} else
							$F.err('Objective - create', data.message);
					}
				})
			}
			return new Objective(project, objectiveFields, oblistFields, objectiveRelatoinWithObList, extTBName, wo3, dbPool);
		}
	}
});